/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// cg_playerState.cpp - transitions the current player state into a new state
//


#include "cg_local.h"


/*
 ==================
 CG_CheckPlayerStateEvents
 ==================
*/
static void CG_CheckPlayerStateEvents (playerState_t *oldState, playerState_t *newState){

	int		index;
	int		i;

	if (!cg.predictedPlayerEntity.state)
		return;

	for (i = newState->eventSequence - MAX_EVENTS; i < newState->eventSequence; i++){
		index = i & (MAX_EVENTS - 1);

		if (i >= oldState->eventSequence){
			CG_EntityEvent(&cg.predictedPlayerEntity, newState->eventTypes[index], newState->eventParms[index]);
			continue;
		}

		if (i > oldState->eventSequence - MAX_EVENTS && newState->eventTypes[index] != oldState->eventTypes[index]){
			CG_EntityEvent(&cg.predictedPlayerEntity, newState->eventTypes[index], newState->eventParms[index]);
			continue;
		}
	}
}

/*
 ==================
 CG_TransitionPlayerState
 ==================
*/
void CG_TransitionPlayerState (playerState_t *oldState, playerState_t *newState){

	int		timeDelta;

	// Check for changing follow mode
	if (newState->clientNum != oldState->clientNum){
		// No error decay on player movement
		cg.thisFrameTeleport = true;

		// Make sure we don't get any unwanted transition effects
		glqMemory->Copy(oldState, newState, sizeof(playerState_t));
	}

	// Smooth view height changes
	if (newState->viewHeight != oldState->viewHeight){
		timeDelta = cg.time - cg.viewHeightTime;
		if (timeDelta >= 250)
			cg.viewHeightDelta = 0.0f;
		else
			cg.viewHeightDelta = cg.viewHeightDelta * (250 - timeDelta) / 250;

		cg.viewHeightDelta += newState->viewHeight - oldState->viewHeight;
		cg.viewHeightTime = cg.time;

		if (oldState->pmType == PM_DEAD && newState->pmType != PM_DEAD){
			cg.viewHeightDelta = 0.0f;
			cg.viewHeightTime = cg.time - 250;
		}
	}

	// Check for events
	CG_CheckPlayerStateEvents(oldState, newState);
}